// <com.woyouqiu.Copyright>
// --------------------------------------------------------------
// <copyright>上海有求网络科技有限公司 2015</copyright>
// <Solution>Vecen.BangChuang</Solution>
// <Project>Vecen.BangChuang.Application</Project>
// <FileName>UserAddressAppService.cs</FileName>
// <CreateTime>2017-04-27 23:03</CreateTime>
// <Author>何苗</Author>
// <Email>hemiao@woyouqiu.com</Email>
// <log date="2017-04-27 23:03" version="00001">创建</log>
// --------------------------------------------------------------
// </com.woyouqiu.Copyright>

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.Runtime.Session;
using Abp.UI;
using Vecen.BangChuang.BangChuang.Areas;
using Vecen.BangChuang.BangChuang.Areas.DomainDtos;
using Vecen.BangChuang.BangChuang.Areas.Dtos;
using Vecen.BangChuang.BangChuang.Mall.Dtos;

namespace Vecen.BangChuang.BangChuang.Mall {

    /// <summary>
    /// 用户地址操作
    /// </summary>
    [AbpAuthorize()]
    public class UserAddressAppService: BangChuangAppServiceBase, IUserAddressAppService {
        private readonly IRepository<UserAddress> _userAddressRepository;
        private readonly CityDomainService _cityDomainService;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userAddressRepository"></param>
        /// <param name="cityDomainService"></param>
        public UserAddressAppService(IRepository<UserAddress> userAddressRepository,
            CityDomainService cityDomainService) {
            _userAddressRepository = userAddressRepository;
            _cityDomainService = cityDomainService;
        }

        /// <summary>
        /// 添加收货地址
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task CreateAsync(UserAddressCreateRequestDto input) {
            var entity = input.MapTo<UserAddress>();
            entity.AreaCode = _cityDomainService.GetAreaIdNotNull(input.ProvinceId, input.CityId, input.DistrictId);
            entity.UserId = AbpSession.GetUserId();
            await _userAddressRepository.InsertAndGetIdAsync(entity);
        }

        /// <summary>
        /// 获得当前用户的所有收货地址
        /// </summary>
        /// <returns></returns>
        public async Task<ListResultDto<UserAddressOutDto>> GetUserAddressesAsync() {
            var entities = await Task.Run(() => _userAddressRepository.GetAll()
                .Where(c => c.UserId == AbpSession.UserId)
                .ToList());
            var dtos = new List<UserAddressOutDto>();
            foreach(var userAddress in entities) {
                var dto = userAddress.MapTo<UserAddressOutDto>();
                dto.AreaData = (await _cityDomainService.GetFullAddressByCityId(userAddress.AreaCode))
                    .MapTo<FullCityOutDto>();

                dtos.Add(dto);
            }

            return new ListResultDto<UserAddressOutDto>(dtos);
        }

        /// <summary>
        /// 设置某个地址为默认
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task SetDefaultAsync(int id) {
            var all = _userAddressRepository.GetAll().Where(c => c.UserId == AbpSession.UserId).ToList();

            foreach(var address in all) {
                address.IsDefault = address.Id == id;
                await _userAddressRepository.UpdateAsync(address);
            }
        }

        /// <summary>
        /// 获取当前用户默认收货地址
        /// </summary>
        /// <returns></returns>
        public async Task<UserAddressOutDto> GetDefaultAsync() {
            var address =
                await _userAddressRepository.FirstOrDefaultAsync(c => c.UserId == AbpSession.UserId && c.IsDefault)
                ?? await _userAddressRepository.FirstOrDefaultAsync(c => c.UserId == AbpSession.UserId);
            var dto = address.MapTo<UserAddressOutDto>();
            if(address != null) {
                dto.AreaData =
                    (await _cityDomainService.GetFullAddressByCityId(address.AreaCode)).MapTo<FullCityOutDto>();
            }
            return dto;
        }

        /// <summary>
        /// 删除收货地址
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task DeleteAsync(int id) {
            var address = await _userAddressRepository.FirstOrDefaultAsync(id);
            if(address.UserId != AbpSession.UserId) {
                throw new UserFriendlyException("删除地址失败!", "这个地址不是你的,不能删除!");
            }
            await _userAddressRepository.DeleteAsync(id);
        }

        /// <summary>
        /// 修改收货地址
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task UpdateAddressAsync(UserAddressCreateRequestDto input) {
            var entity = input.MapTo<UserAddress>();
            entity.AreaCode = _cityDomainService.GetAreaIdNotNull(input.ProvinceId, input.CityId, input.DistrictId);
            entity.UserId = AbpSession.GetUserId();
            await _userAddressRepository.InsertOrUpdateAndGetIdAsync(entity);
        }
    }
}